package base;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import static base.DataConverter.CONVERTERS;

public class DataReader{
    private String filePath;

    public String getFilePath() {
        checkFilePath();
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }

    @SuppressWarnings("unchecked")
    private <T> Function<String, T> getConverter(Class<T> targetType) {
        if (targetType == null) {
            throw new IllegalArgumentException("Target type must not be null");
        }
        Function<String, ?> converter = CONVERTERS.get(targetType);
        if (converter == null) {
            throw new IllegalArgumentException("Unsupported type: " + targetType);
        }
        return (Function<String, T>) converter;
    }

    public final <T> List<T> readFile(String split, Class<T> targetType) throws Exception {
        checkFilePath();
        List<String> lines = Files.readAllLines(Paths.get(filePath));
        Function<String, T> converter = getConverter(targetType);
        List<T> result = new ArrayList<>();
        for (String line : lines) {
            String[] parts = line.split(split);
            for (String part : parts) {
                T converted = converter.apply(part.trim());
                result.add(converted);
            }
        }
        return result;
    }

    private String[] readFile(String split) throws IOException {
        checkFilePath();
        return Files.readAllLines(Paths.get(filePath)).get(0).split(split);
    }
    public final int[] readFileInt(String split) throws Exception {
        checkFilePath();
        return Arrays.stream(readFile(split)).mapToInt(Integer::parseInt).toArray();
    }
    public final long[] readFileLong(String split) throws Exception {
        checkFilePath();
        return Arrays.stream(readFile(split)).mapToLong(Long::parseLong).toArray();
    }
    public final double[] readFileDouble(String split) throws Exception {
        checkFilePath();
        return Arrays.stream(readFile(split)).mapToDouble(Double::parseDouble).toArray();
    }
    public final String[] readFileString(String split) throws Exception {
        checkFilePath();
        return readFile(split);
    }

    private void checkFilePath() {
        if (!filePathExist()) {
            throw new IllegalArgumentException("File path must be set");
        }
    }

    private boolean filePathExist() {
        return filePath != null && !filePath.isEmpty();
    }
}
